﻿using Google.Protobuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

class MessageDispatcher
{
#if !SERVER
    public static MessageDispatcher Instance = new MessageDispatcher();
#endif

    Dictionary<EMessageType, List<Action<IMessage>>> m_MessageDict = new Dictionary<EMessageType, List<Action<IMessage>>>();
    Dictionary<int, Action<IMessage>> m_ActionDict = new Dictionary<int, Action<IMessage>>();
    
    public void Register<T>(EMessageType type, Action<T> callback)
        where T : IMessage
    {
        if (callback == null)
        {
            return;
        }

        if (!m_MessageDict.ContainsKey(type))
        {
            m_MessageDict.Add(type, new List<Action<IMessage>>());
        }
        if (!m_ActionDict.ContainsKey(callback.GetHashCode()))
        { 
            Action<IMessage> a = (msg) => callback((T)msg);
            m_ActionDict.Add(callback.GetHashCode(),a);
            m_MessageDict[type].Add(a);
        }
    }

    public void Unregister<T>(EMessageType type, Action<T> callback)
        where T : IMessage
    {
        if (callback == null)
        {
            return;
        }

        if (m_ActionDict.ContainsKey(callback.GetHashCode()))
        {
            var a = m_ActionDict[callback.GetHashCode()];
            if (m_MessageDict.ContainsKey(type))
            { 
                m_MessageDict[type].Remove(a);
            }
            m_ActionDict.Remove(callback.GetHashCode());
        }
    }

    public void Invoke<T>(EMessageType type, T msg)
        where T : IMessage
    {
        if (msg == null)
        {
            return;
        }

        if (m_MessageDict.ContainsKey(type))
        {
            foreach (var item in m_MessageDict[type])
            {
                item.Invoke(msg);
            }
        }
    }
}
